package com.inossem.warehousestorage_inossem.utils;

import com.inossem.utils.enumeration.SortEnum;
import com.inossem.utils.log.LogUtils;

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.List;

/**
 * Created by leij on 2018/2/2.
 */

public class BeanUtils {

    private static final Class[] baseTypeList = {String.class, byte.class, Byte.class, short.class, Short.class, int.class, Integer.class, long.class, Long.class, float.class, Float.class, double.class, Double.class, char.class, Character.class, boolean.class, Boolean.class};

    private static final String DISPLAY_INDEX = "display_index";

    private static final String _RID = "_rid";

    private static final String[] SORT_NAMES = {DISPLAY_INDEX, _RID};

    private static <T> List<T> sortGenerics(List<T> list, final String[] sortNames, final SortEnum... sortEnum) {
        String name = hasField(list, sortNames);
        if (name != null) {
            LogUtils.i("排序");
            Collections.sort(list, (t1, t2) -> {
                try {
                    Field fieldT1 = t1.getClass().getDeclaredField(name);
                    Field fieldT2 = t2.getClass().getDeclaredField(name);
                    fieldT1.setAccessible(true);
                    fieldT2.setAccessible(true);
                    Integer indexT1 = Integer.parseInt((fieldT1.get(t1) == null ? "-1" : (String) fieldT1.get(t1)));
                    Integer indexT2 = Integer.parseInt((fieldT2.get(t2) == null ? "-1" : (String) fieldT2.get(t2)));
                    if (sortEnum == null || sortEnum.length != 1) {
                        return indexT1.compareTo(indexT2);
                    } else if (sortEnum[0] == SortEnum.ASC) {
                        return indexT1.compareTo(indexT2);
                    } else if (sortEnum[0] == SortEnum.DESC) {
                        return indexT2.compareTo(indexT1);
                    } else {
                        return indexT1.compareTo(indexT2);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    return 0;
                }
            });
        }
        return list;
    }

    private static <T> String hasField(List<T> list, String[] sortNames) {
        if (list != null && !list.isEmpty()) {
            for (int i = 0; i < sortNames.length; i++) {
                Field[] fields = list.get(0).getClass().getDeclaredFields();
                for (int j = 0; j < fields.length; j++) {
                    if (fields[j].getName().endsWith(sortNames[i])) {
                        return sortNames[i];
                    }
                }
            }
            return null;
        } else {
            return null;
        }
    }

    public static <T> T sortBean(T bean, final SortEnum... sortEnum) {
        return sortBean(bean, SORT_NAMES, sortEnum);
    }

    private static <T> T sortBean(T bean, String[] sortName, final SortEnum... sortEnum) {
        try {
            Field[] fields = bean.getClass().getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                LogUtils.i("name【" + fields[i].getName() + "】---type【" + fields[i].getType().getSimpleName() + "】");
                fields[i].setAccessible(true);
                if (fields[i].getType() == List.class) {
                    List list = (List) fields[i].get(bean);
                    if (list != null && !list.isEmpty()) {
                        for (int j = 0; j < list.size(); j++) {
                            sortBean(list.get(j), sortName, sortEnum);
                        }
                    }
                    fields[i].set(bean, sortGenerics(list, sortName, sortEnum));
                } else if (!isBaseType(fields[i].getType())) {
                    sortBean(fields[i].get(bean), sortName, sortEnum);
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return bean;
    }

    private static boolean isBaseType(Class<?> type) {
        for (int i = 0; i < baseTypeList.length; i++) {
            if (baseTypeList[i] == type) {
                return true;
            }
        }
        return false;
    }

}
